/* Class that handles the Categories/SubCategories ExpandableListView seen in the Categories screen * Does everything from setting up the view to Add/Delete/Edit */ package com.databases.example.features.categories; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v4.app.DialogFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.SearchView; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ExpandableListView; import android.widget.ExpandableListView.ExpandableListContextMenuInfo; import com.databases.example.R; import com.databases.example.app.BaseActivity; import com.databases.example.database.DatabaseHelper; import com.databases.example.database.MyContentProvider; import com.databases.example.features.search.SearchWidget; import com.databases.example.utils.Constants; import java.util.ArrayList; import timber.log.Timber; public class CategoriesActivity extends BaseActivity implements OnSharedPreferenceChangeListener, LoaderManager.LoaderCallbacks<Cursor> { public static final int CATEGORIES_LOADER = 8675309; public static final int SUBCATEGORIES_LOADER = 867; public CategoriesListViewAdapter adapterCategory; //Constants for ContextMenu (Category) private final int CONTEXT_MENU_CATEGORY_ADD = 1; private final int CONTEXT_MENU_CATEGORY_VIEW = 2; private final int CONTEXT_MENU_CATEGORY_EDIT = 3; private final int CONTEXT_MENU_CATEGORY_DELETE = 4; //Constants for ContextMenu (SubCategory) private final int CONTEXT_MENU_SUBCATEGORY_VIEW = 5; private final int CONTEXT_MENU_SUBCATEGORY_EDIT = 6; private final int CONTEXT_MENU_SUBCATEGORY_DELETE = 7; private static DatabaseHelper dh = null; private final ArrayList<Cursor> resultsCursor = new ArrayList<Cursor>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); dh = new DatabaseHelper(this); setContentView(R.layout.categories); setTitle(getString(R.string.categories)); ExpandableListView listViewCategories = (ExpandableListView) this.findViewById(R.id.category_list); //Turn clicks on listViewCategories.setClickable(true); listViewCategories.setLongClickable(true); //Allows Context Menus for each item of the list view registerForContextMenu(listViewCategories); //Set up a listener for changes in settings menu SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); prefs.registerOnSharedPreferenceChangeListener(this); getSupportLoaderManager().initLoader(CATEGORIES_LOADER, null, this); adapterCategory = new CategoriesListViewAdapter(this, 0, null, resultsCursor); listViewCategories.setAdapter(adapterCategory); } public CategoriesListViewAdapter getAdapterCategory() { return adapterCategory; } public void setAdapterCategory(CategoriesListViewAdapter adapterCategory) { this.adapterCategory = adapterCategory; } //Method for filling subcategories public void subcategoryPopulate(int catId) { Cursor cursorSubCategory = dh.getSubCategories(null, DatabaseHelper.SUBCATEGORY_CAT_ID + "=" + catId, null, null); resultsCursor.add(cursorSubCategory); }//end of subcategoryPopulate //Adding a new category private void categoryAdd(android.view.MenuItem item) { //SubCategory Add if (item != null) { ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo(); int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); DialogFragment newFragment = CategoryAddFragment.newInstance(groupPos, childPos); newFragment.show(getSupportFragmentManager(), "dialogAdd"); } //CategoryAdd else { DialogFragment newFragment = CategoryAddFragment.newInstance(); newFragment.show(getSupportFragmentManager(), "dialogAdd"); } }//end of showCategoryAdd //Delete Category private void categoryDelete(android.view.MenuItem item) { ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo(); int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); int type = ExpandableListView.getPackedPositionType(info.packedPosition); if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { int subcategoryID = adapterCategory.getSubCategory(groupPos, childPos).id; Uri uri = Uri.parse(MyContentProvider.SUBCATEGORIES_URI + "/" + subcategoryID); getContentResolver().delete(uri, DatabaseHelper.SUBCATEGORY_ID + "=" + subcategoryID, null); Timber.d("Deleting " + adapterCategory.getSubCategory(groupPos, childPos).name + " id:" + subcategoryID); } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { int categoryID = adapterCategory.getCategory(groupPos).id; //Delete category Uri uri = Uri.parse(MyContentProvider.CATEGORIES_URI + "/" + categoryID); getContentResolver().delete(uri, DatabaseHelper.CATEGORY_ID + "=" + categoryID, null); //Delete remaining subcategories uri = Uri.parse(MyContentProvider.SUBCATEGORIES_URI + "/" + 0); getContentResolver().delete(uri, DatabaseHelper.SUBCATEGORY_CAT_ID + "=" + categoryID, null); Timber.d("Deleting " + adapterCategory.getCategory(groupPos).name + " id:" + categoryID); } getSupportLoaderManager().restartLoader(CATEGORIES_LOADER, null, this); }//end categoryDelete //Edit Category private void categoryEdit(android.view.MenuItem item) { ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo(); final int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); final int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); final int type = ExpandableListView.getPackedPositionType(info.packedPosition); DialogFragment newFragment = CategoryEditFragment.newInstance(groupPos, childPos, type); newFragment.show(getSupportFragmentManager(), "dialogEdit"); } //View Category private void categoryView(android.view.MenuItem item) { ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo(); final int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); final int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); final int type = ExpandableListView.getPackedPositionType(info.packedPosition); DialogFragment newFragment = CategoryViewFragment.newInstance(groupPos, childPos, type); newFragment.show(getSupportFragmentManager(), "dialogView"); } //For ActionBar Menu @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); //Show SearchActivity MenuItem menuSearch = menu.add(Menu.NONE, R.id.account_menu_search, Menu.NONE, "SearchActivity"); menuSearch.setIcon(android.R.drawable.ic_menu_search); menuSearch.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); menuSearch.setActionView(new SearchView(getSupportActionBar().getThemedContext())); new SearchWidget(this, (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.account_menu_search))); //Show Add Icon MenuItem menuAdd = menu.add(Menu.NONE, R.id.account_menu_add, Menu.NONE, "Add"); menuAdd.setIcon(android.R.drawable.ic_menu_add); menuAdd.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); return true; } //For ActionBar Menu Items (and home icon) @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.account_menu_add: categoryAdd(null); return true; } return super.onOptionsItemSelected(item); } //Creates menu for long presses @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuInfo; int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); int type = ExpandableListView.getPackedPositionType(info.packedPosition); switch (type) { case ExpandableListView.PACKED_POSITION_TYPE_CHILD: String nameSubCategory = adapterCategory.getSubCategory(groupPos, childPos).name; menu.setHeaderTitle(nameSubCategory); menu.add(0, CONTEXT_MENU_SUBCATEGORY_VIEW, 1, getString(R.string.view)); menu.add(0, CONTEXT_MENU_SUBCATEGORY_EDIT, 2, getString(R.string.edit)); menu.add(0, CONTEXT_MENU_SUBCATEGORY_DELETE, 3, getString(R.string.delete)); break; case ExpandableListView.PACKED_POSITION_TYPE_GROUP: String nameCategory = adapterCategory.getCategory(groupPos).name; menu.add(1, CONTEXT_MENU_CATEGORY_ADD, 0, getString(R.string.add)); menu.setHeaderTitle(nameCategory); menu.add(1, CONTEXT_MENU_CATEGORY_VIEW, 1, getString(R.string.view)); menu.add(1, CONTEXT_MENU_CATEGORY_EDIT, 2, getString(R.string.edit)); menu.add(1, CONTEXT_MENU_CATEGORY_DELETE, 3, getString(R.string.delete)); break; default: Timber.e("Context Menu type is not child or group"); break; } } //Handles which methods are called when using the long presses menu @Override public boolean onContextItemSelected(android.view.MenuItem item) { switch (item.getItemId()) { case CONTEXT_MENU_CATEGORY_ADD: categoryAdd(item); return true; case CONTEXT_MENU_CATEGORY_VIEW: categoryView(item); return true; case CONTEXT_MENU_CATEGORY_EDIT: categoryEdit(item); return true; case CONTEXT_MENU_CATEGORY_DELETE: categoryDelete(item); return true; case CONTEXT_MENU_SUBCATEGORY_VIEW: categoryView(item); return true; case CONTEXT_MENU_SUBCATEGORY_EDIT: categoryEdit(item); return true; case CONTEXT_MENU_SUBCATEGORY_DELETE: categoryDelete(item); return true; default: Timber.e("Context Menu type is not child or group"); break; } return super.onContextItemSelected(item); } //Used after a change in settings occurs @Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { //Toast.makeText(this, "OptionsActivity Just Changed: CategoriesActivity.Java", Toast.LENGTH_SHORT).show(); //categoryPopulate(); } @Override public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle) { Timber.v("calling create loader..."); switch (loaderID) { case CATEGORIES_LOADER: Timber.v("new category loader created"); return new CursorLoader( this, // Parent activity context MyContentProvider.CATEGORIES_URI,// Table to query null, // Projection to return null, // No selection clause null, // No selection arguments null // Default sort order-> "CAST (AcctBalance AS INTEGER)" + " DESC" ); case SUBCATEGORIES_LOADER: Timber.v("new subcategory loader created"); String selection = DatabaseHelper.SUBCATEGORY_CAT_ID + "=" + bundle.getString("id"); return new CursorLoader( this, // Parent activity context MyContentProvider.SUBCATEGORIES_URI,// Table to query null, // Projection to return selection, // No selection clause null, // No selection arguments null // Default sort order ); default: Timber.e("Not a valid CursorLoader ID"); return null; } } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { switch (loader.getId()) { case CATEGORIES_LOADER: adapterCategory.swapCategoryCursor(data); Timber.v("loader finished. loader=" + loader.getId() + " data=" + data + " data size=" + data.getCount()); data.moveToPosition(-1); while (data.moveToNext()) { //Bundle bundle = new Bundle(); //bundle.putString("id", data.getString(0)); //getSupportLoaderManager().restartLoader(SUBCATEGORIES_LOADER, bundle, this); subcategoryPopulate(data.getInt(0)); } break; case SUBCATEGORIES_LOADER: adapterCategory.swapSubCategoryCursor(data); Timber.v("loader finished. loader=" + loader.getId() + " data=" + data + " data size=" + data.getCount()); break; default: Timber.e("Error. Unknown loader (" + loader.getId()); break; } } @Override public void onLoaderReset(Loader<Cursor> loader) { switch (loader.getId()) { case CATEGORIES_LOADER: adapterCategory.swapCategoryCursor(null); Timber.v("loader reset. loader=" + loader.getId()); break; case SUBCATEGORIES_LOADER: adapterCategory.swapSubCategoryCursor(null); Timber.v("loader reset. loader=" + loader.getId()); break; default: Timber.e("Error. Unknown loader (" + loader.getId()); break; } } @Override public Constants.ActivityTag setDrawerTag() { return Constants.ActivityTag.CATEGROIES; } }